package com.ql.service.user;

import com.ql.dao.yk.YpcgMapper;
import com.ql.pojo.user.*;
import com.ql.pojo.yk.PageResult;
import com.ql.pojo.yk.Ypcg;
import com.ql.utils.SessionUtils;
import org.activiti.engine.*;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.zip.ZipInputStream;

@Service
public class WorkFlowServiceImpl implements  WorkFlowService {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private IdentityService identityService;

    @Autowired
    private FormService formService;

    @Autowired
    private TaskService taskService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private ManagementService managementService;

    @Autowired
    private YpcgMapper ypcgMapper;

    /**
     * 查询流程部署信息
     * @return
     */
    public DataGridView queryProcessDeploy(WorkFlowVo workFlowVo){
        if(null==workFlowVo.getDeploymentName()){
            workFlowVo.setDeploymentName("");
        }
        String name = workFlowVo.getDeploymentName();
        //查询总条数
        long count =repositoryService.createDeploymentQuery().deploymentNameLike("%"+name+"%").count();
        //查询
        int firstResult =(workFlowVo.getPage()-1)*workFlowVo.getLimit();
        int maxResults=workFlowVo.getLimit();
        List<Deployment> list = repositoryService.createDeploymentQuery().deploymentNameLike("%" + name + "%").listPage(firstResult, maxResults);
        List<ActDeploymentEntity> data = new ArrayList<ActDeploymentEntity>();
        for (Deployment deployment:list) {
            ActDeploymentEntity entity = new ActDeploymentEntity();
            BeanUtils.copyProperties(deployment,entity);
            data.add(entity);
        }
        return  new DataGridView(count,data);
    }

    public DataGridView queryAllProcessDefinition(WorkFlowVo workFlowVo) {
        if(workFlowVo.getDeploymentName()==null){
            workFlowVo.setDeploymentName("");
        }
        String name = workFlowVo.getDeploymentName();
        //现根据部署的名称模糊查询出所有的部署的ID
        List<Deployment> dlist = repositoryService.createDeploymentQuery().deploymentNameLike("%" + name +"%").list();
        List<String> Ids= new ArrayList<String>();
        for (Deployment deployment:dlist
             ) {
            Ids.add(deployment.getId());
        }
        long count=0;
        List<ActProcessDefinitionEntity> data= new ArrayList<ActProcessDefinitionEntity>();;
        if(Ids.size()>0) {

            for (String id:Ids
                 ) {
                count = this.repositoryService.createProcessDefinitionQuery().deploymentId(id).count();

                int firstResult = (workFlowVo.getPage() - 1) * workFlowVo.getLimit();
                int maxResults = workFlowVo.getLimit();
                List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().deploymentId(id).listPage(firstResult, maxResults);
                for (ProcessDefinition processDefinition : list) {
                    ActProcessDefinitionEntity entity = new ActProcessDefinitionEntity();
                    BeanUtils.copyProperties(processDefinition, entity);
                    data.add(entity);
                }
            }

        }
        return  new DataGridView(count,data);
    }

    public void addWorkFlow(InputStream inputStream, String deploymentName) {
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        this.repositoryService.createDeployment().name(deploymentName).addZipInputStream(zipInputStream).deploy();

        try {
            zipInputStream.close();
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void deleteWorkFlow(String deploymentId) {
        this.repositoryService.deleteDeployment(deploymentId,true);
    }

    public InputStream queryProcessDeploymentImage(String deploymentId) {
        List<String> names = this.repositoryService.getDeploymentResourceNames(deploymentId);
        // 定义资源图片的名称
        String resourceName="";
        if(names!=null && names.size()>0){
            for (String name : names) {
                if(name.indexOf(".png")>=0){
                    resourceName=name;
                }
            }
        }
        InputStream inputStream=this.repositoryService
                .getResourceAsStream(deploymentId, resourceName);
        //ProcessDefinition processDefinition = this.repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult();
        //InputStream stream = this.repositoryService.getResourceAsStream(deploymentId, resourceName);
        return inputStream;
    }

    @Override
    public void startProcess(Integer cgId) {
        //找到流程的key
        String processKey = Ypcg.class.getSimpleName();

        String busKey = processKey+":"+cgId;
        Map<String,Object> map = new HashMap<>();
        map.put("username", SessionUtils.getCurrentUserName());
        this.runtimeService.startProcessInstanceByKey(processKey,busKey,map);
        Ypcg ypcg = ypcgMapper.selectByPrimaryKey(cgId);
        ypcg.setCgShzt(1);
        this.ypcgMapper.updateByPrimaryKeySelective(ypcg);
    }

    @Override
    public DataGridView queryCurrentUserTask(WorkFlowVo workFlowVo) {
        String assignee = SessionUtils.getCurrentUserName();

        long count = this.taskService.createTaskQuery().taskAssignee(assignee).count();
        int firstResult =(workFlowVo.getPage()-1)*workFlowVo.getLimit();
        int maxResults=workFlowVo.getLimit();
        List<Task> tasks = this.taskService.createTaskQuery().taskAssignee(assignee).listPage(firstResult, maxResults);
        List<ActTaskEntity> taskEntities = new ArrayList<>();
        for (Task task:tasks
             ) {
            ActTaskEntity entity = new ActTaskEntity();
            BeanUtils.copyProperties(task,entity);
            taskEntities.add(entity);
        }
        return new DataGridView(count,taskEntities);

    }

    public Ypcg queryYpcgByTaskId(String taskId) {
        // 1,根据任务ID查询任务实例
        Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
        // 2,从任务里面取出流程实例ID
        String processInstanceId = task.getProcessInstanceId();
        // 3,根据流程实例ID查询流程实例
        ProcessInstance processInstance = this.runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        // 4,取出business_key
        String businessKey = processInstance.getBusinessKey();// LeaveBill:9
        String ypcgId = businessKey.split(":")[1];
        return this.ypcgMapper.selectByPrimaryKey(Integer.valueOf(ypcgId));
    }

    public List<String> queryOutComeByTaskId(String taskId) {
        List<String> names = new ArrayList<>();
        // 1,根据任务ID查询任务实例
        Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
        // 2,取出流程定义ID
        String processDefinitionId = task.getProcessDefinitionId();
        // 3,取出流程实例ID
        String processInstanceId = task.getProcessInstanceId();
        // 4,根据流程实例ID查询流程实例
        ProcessInstance processInstance = this.runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        // 5,根据流程定义ID查询流程定义的XML信息
        ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) this.repositoryService
                .getProcessDefinition(processDefinitionId);
        // 6,从流程实例对象里面取出当前活动节点ID
        String activityId = processInstance.getActivityId();// usertask1
        // 7,使用活动ID取出xml和当前活动ID相关节点数据
        ActivityImpl activityImpl = processDefinition.findActivity(activityId);
        // 8,从activityImpl取出连线信息
        List<PvmTransition> transitions = activityImpl.getOutgoingTransitions();
        if (null != transitions && transitions.size() > 0) {
            // PvmTransition就是连接对象
            for (PvmTransition pvmTransition : transitions) {
                String name = pvmTransition.getProperty("name").toString();
                names.add(name);
            }
        }
        return names;
    }


    /**
     * 根据任务ID查询批注信息
     */
    @Override
    public DataGridView queryCommentByTaskId(String taskId) {
        // 1,根据任务ID查询任务实例
        Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
        // 2,从任务里面取出流程实例ID
        String processInstanceId = task.getProcessInstanceId();
        List<Comment> comments = taskService.getProcessInstanceComments(processInstanceId);
        List<ActCommentEntity> data = new ArrayList<>();
        if (null != comments && comments.size() > 0) {
            for (Comment comment : comments) {
                ActCommentEntity entity = new ActCommentEntity();
                BeanUtils.copyProperties(comment, entity);
                data.add(entity);
            }
        }
        return new DataGridView(Long.valueOf(data.size()), data);
    }


    /**
     * 完成任务
     */
    @Override
    public void completeTask(WorkFlowVo workFlowVo) {
        String taskId = workFlowVo.getTaskId();// 任务ID
        String outcome = workFlowVo.getOutcome();// 连接名称
        Integer YpcgId = workFlowVo.getId();// 请假单ID
        String comment = workFlowVo.getComment();// 批注信息

        // 1,根据任务ID查询任务实例
        Task task = this.taskService.createTaskQuery().taskId(taskId).singleResult();
        // 2,从任务里面取出流程实例ID
        String processInstanceId = task.getProcessInstanceId();
        // 设置批注人名
        String userName = SessionUtils.getCurrentUserName();
        /*
         * 因为批注人是org.activiti.engine.impl.cmd.AddCommentCmd 80代码使用 String userId =
         * Authentication.getAuthenticatedUserId(); CommentEntity comment = new
         * CommentEntity(); comment.setUserId(userId);
         * Authentication这类里面使用了一个ThreadLocal的线程局部变量
         */
        Authentication.setAuthenticatedUserId(userName);
        // 添加批注信息
        this.taskService.addComment(taskId, processInstanceId, "[" + outcome + "]" + comment);
        // 完成任务
        Map<String, Object> variables = new HashMap<>();
        variables.put("outcome", outcome);
        this.taskService.complete(taskId, variables);
        // 判断任务是否结束
        ProcessInstance processInstance = this.runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId).singleResult();
        if (null == processInstance) {
            Ypcg ypcg = new Ypcg();
            ypcg.setCgId(YpcgId);
            // 说明流程结束
            if (outcome.equals("放弃")) {
                ypcg.setCgShzt(3);// 已放弃
            } else {
                ypcg.setCgShzt(2);// 审批完成
            }
            this.ypcgMapper.updateByPrimaryKeySelective(ypcg);
        }

    }
}
